/**
 * 命令队列使用示例
 * 
 * 展示如何在逻辑系统和渲染系统之间使用命令队列进行通信
 * 
 * @author AI Assistant
 * @date 2025-11-26
 */

import { ecs } from "../../../core/ecs/ECS";
import { Vec3, Color } from "cc";
import { commandQueue, CommandType, CommandPriority, renderCommandExecutor } from "./index";
import { LogicCmd } from "./LogicCommandHelper";
import { ViewComponent } from "../component/ViewComponent";
import { renderSystem } from "../render/renderSystem";

// ==================== 示例 1: 基础使用 ====================

/**
 * 示例：在逻辑系统中发送命令
 */
export class MovementLogicSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
    filter(): ecs.IMatcher {
        // 假设有 PositionComponent 和 VelocityComponent
        return ecs.allOf(ViewComponent);
    }
    
    update(entity: ecs.Entity): void {
        // 逻辑层计算新位置
        const newX = 100;
        const newY = 200;
        
        // ✅ 通过命令队列发送渲染命令
        LogicCmd.setPosition(entity.eid, newX, newY);
        
        // 不要直接操作节点！
        // ❌ viewComp.node.setPosition(newX, newY);
    }
}

// ==================== 示例 2: 战斗系统 ====================

/**
 * 示例：战斗系统发送多个渲染命令
 */
export class CombatLogicSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
    filter(): ecs.IMatcher {
        // 假设有 HealthComponent 和 ViewComponent
        return ecs.allOf(ViewComponent);
    }
    
    update(entity: ecs.Entity): void {
        // 模拟：实体受到攻击
        const isHit = Math.random() > 0.99;
        
        if (isHit) {
            // 1. 播放受击动画
            LogicCmd.playAnimation(entity.eid, 'hit', false);
            
            // 2. 闪烁效果（使用 HIGH 优先级）
            LogicCmd.setSpriteOpacity(entity.eid, 128, CommandPriority.HIGH);
            
            // 3. 延迟恢复透明度（通过回调）
            setTimeout(() => {
                LogicCmd.setSpriteOpacity(entity.eid, 255);
            }, 200);
            
            // 4. 如果死亡，隐藏实体
            const isDead = Math.random() > 0.9;
            if (isDead) {
                LogicCmd.hide(entity.eid);
                
                // 延迟销毁
                setTimeout(() => {
                    LogicCmd.destroyNode(entity.eid);
                }, 1000);
            }
        }
    }
}

// ==================== 示例 3: UI 系统 ====================

/**
 * 示例：UI 系统更新文本和颜色
 */
export class UILogicSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
    private score: number = 0;
    
    filter(): ecs.IMatcher {
        // 假设有 UIComponent 和 ViewComponent
        return ecs.allOf(ViewComponent);
    }
    
    update(entity: ecs.Entity): void {
        // 更新分数
        this.score += 10;
        
        // 1. 更新文本
        LogicCmd.setLabelText(entity.eid, `Score: ${this.score}`);
        
        // 2. 根据分数改变颜色
        if (this.score > 1000) {
            LogicCmd.setLabelColor(entity.eid, new Color(255, 215, 0)); // 金色
        } else if (this.score > 500) {
            LogicCmd.setLabelColor(entity.eid, new Color(255, 0, 0)); // 红色
        } else {
            LogicCmd.setLabelColor(entity.eid, new Color(255, 255, 255)); // 白色
        }
    }
}

// ==================== 示例 4: 批量操作 ====================

/**
 * 示例：批量更新敌人位置
 */
export function batchUpdateEnemies(enemies: ecs.Entity[]): void {
    // 准备批量位置数据
    const positions = enemies.map((enemy, index) => ({
        entityId: enemy.eid,
        x: Math.cos(index) * 100,
        y: Math.sin(index) * 100,
        z: 0
    }));
    
    // 批量发送位置更新命令
    LogicCmd.batchSetPosition(positions);
    
    console.log(`批量更新了 ${enemies.length} 个敌人的位置`);
}

// ==================== 示例 5: 动画序列 ====================

/**
 * 示例：播放一个动画序列
 */
export function playAnimationSequence(entityId: number): void {
    // 1. 播放待机动画
    LogicCmd.playAnimation(entityId, 'idle', true);
    
    // 2. 2秒后播放攻击动画
    setTimeout(() => {
        LogicCmd.playAnimation(entityId, 'attack', false, CommandPriority.HIGH);
    }, 2000);
    
    // 3. 攻击动画结束后恢复待机（假设攻击动画 1 秒）
    setTimeout(() => {
        LogicCmd.playAnimation(entityId, 'idle', true);
    }, 3000);
}

// ==================== 示例 6: 渲染系统集成 ====================

/**
 * 渲染系统：执行命令队列
 */
export class CommandExecutionRenderSystem extends ecs.ComblockSystem {
    filter(): ecs.IMatcher {
        // 渲染系统不需要过滤实体
        return ecs.allOf();
    }
    
    /**
     * 在渲染系统的 execute 中执行命令队列
     */
    execute(dt: number): void {
        // 执行所有待处理的命令
        // 设置最大执行时间为 16ms（60 FPS）
        commandQueue.executeAll(16);
    }
}

// ==================== 示例 7: 完整游戏流程 ====================

/**
 * 完整示例：创建实体并通过命令队列控制
 */
export async function completeGameFlowExample(): Promise<void> {
    console.log('\n========== 命令队列完整示例 ==========\n');
    
    // 1. 初始化命令队列（注册执行器）
    console.log('1. 初始化命令队列');
    initializeCommandQueue();
    
    // 2. 创建玩家实体
    console.log('2. 创建玩家实体');
    const player = ecs.getEntity(ecs.Entity);
    const playerNode = await renderSystem.createEntityView(
        player,
        'game',
        'prefabs/player',
        'game'
    );
    
    if (!playerNode) {
        console.error('玩家创建失败');
        return;
    }
    
    console.log(`玩家创建成功，实体 ID: ${player.eid}`);
    
    // 3. 通过命令队列操作玩家
    console.log('\n3. 发送命令到队列');
    
    // 设置初始位置
    LogicCmd.setPosition(player.eid, 0, 0, 0);
    console.log('  - 设置位置命令');
    
    // 播放待机动画
    LogicCmd.playAnimation(player.eid, 'idle', true);
    console.log('  - 播放动画命令');
    
    // 设置颜色
    LogicCmd.setSpriteColor(player.eid, new Color(255, 255, 255));
    console.log('  - 设置颜色命令');
    
    console.log(`\n当前队列中的命令数: ${commandQueue.getTotalCommandCount()}`);
    
    // 4. 执行命令队列
    console.log('\n4. 执行命令队列');
    commandQueue.executeAll();
    console.log('命令执行完成');
    
    // 5. 查看统计信息
    console.log('\n5. 统计信息');
    commandQueue.printStats();
    
    // 6. 模拟游戏循环
    console.log('\n6. 模拟游戏循环（移动玩家）');
    simulateGameLoop(player.eid, 10);
    
    console.log('\n========== 示例完成 ==========\n');
}

/**
 * 初始化命令队列
 */
function initializeCommandQueue(): void {
    // 注册渲染命令执行器
    const supportedCommands = [
        CommandType.SET_POSITION,
        CommandType.SET_ROTATION,
        CommandType.SET_SCALE,
        CommandType.SET_VISIBLE,
        CommandType.SET_ACTIVE,
        CommandType.PLAY_ANIMATION,
        CommandType.STOP_ANIMATION,
        CommandType.PAUSE_ANIMATION,
        CommandType.SET_SPRITE_FRAME,
        CommandType.SET_SPRITE_COLOR,
        CommandType.SET_SPRITE_OPACITY,
        CommandType.SET_LABEL_TEXT,
        CommandType.SET_LABEL_COLOR,
        CommandType.DESTROY_NODE
    ];
    
    for (const commandType of supportedCommands) {
        commandQueue.registerExecutor(commandType, renderCommandExecutor);
    }
    
    console.log(`注册了 ${supportedCommands.length} 个命令执行器`);
}

/**
 * 模拟游戏循环
 */
function simulateGameLoop(entityId: number, frames: number): void {
    let currentFrame = 0;
    
    const interval = setInterval(() => {
        currentFrame++;
        
        // 每帧移动一点
        const x = Math.cos(currentFrame * 0.1) * 100;
        const y = Math.sin(currentFrame * 0.1) * 100;
        
        LogicCmd.setPosition(entityId, x, y);
        
        // 执行命令队列
        commandQueue.executeAll();
        
        if (currentFrame >= frames) {
            clearInterval(interval);
            console.log(`游戏循环结束（${frames} 帧）`);
            commandQueue.printStats();
        }
    }, 16); // 60 FPS
}

// ==================== 导出便捷接口 ====================

export const CommandQueueExamples = {
    completeFlow: completeGameFlowExample,
    batchUpdateEnemies,
    playAnimationSequence,
    initializeCommandQueue
};

// 在控制台使用：
// import { CommandQueueExamples } from 'db://assets/scripts/ecs/command/CommandQueueExample';
// await CommandQueueExamples.completeFlow();

